home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programmer Power Tools
/
Programmer Power Tools.iso
/
tiff
/
tiffdum4.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-11-02
|
9KB
|
375 lines
/* tiffdump - dump a tiff file, to avoid painful hex dumps
*/
#include "aldtypes.h"
#include "imtypes.h"
#include "tiff.h"
#include "imag.h"
#include "imtiff.h"
#include "vio.h"
#include "stdio.h"
#include "dloc.h"
/* prototypes:
*/
#ifdef MACINTOSH
FILE * fopen (char *, char *);
int fseek (FILE *, long, int);
int fread (char *, int, int, FILE *);
int fclose (FILE *);
#endif
static struct {
WORD tag;
char *str;
} tagstr[] = {
TGNEWSUBFILETYPE, "NewSubfileType",
TGOLDSUBFILETYPE, "OldSubfileType",
TGIMAGEWIDTH, "ImageWidth",
TGIMAGELENGTH, "ImageLength",
TGCOMPRESSION, "Compression",
TGPHOTOMETRICINTERPRETATION,"PhotometricInterp",
TGTHRESHHOLDING, "Threshholding",
TGCELLWIDTH, "CellWidth",
TGCELLLENGTH, "CellLength",
TGFILLORDER, "FillOrder",
TGSTRIPOFFSETS, "StripOffsets",
TGORIENTATION, "Orientation",
TGSAMPLESPERPIXEL, "SamplesPerPixel",
TGBITSPERSAMPLE, "BitsPerSample",
TGROWSPERSTRIP, "RowsPerStrip",
TGSTRIPBYTECOUNTS, "StripByteCounts",
TGMINSAMPLEVALUE, "MinSampleValue",
TGMAXSAMPLEVALUE, "MaxSampleValue",
TGXRESOLUTION, "XResolution",
TGYRESOLUTION, "YResolution",
TGPLANARCONFIGURATION, "PlanarConfiguration",
TGDOCUMENTNAME, "DocumentName",
TGPAGENAME, "PageName",
TGXPOSITION, "XPosition",
TGYPOSITION, "YPosition",
TGIMAGEDESCRIPTION, "ImageDescription",
TGMAKE, "Make",
TGMODEL, "Model",
TGFREEOFFSETS, "FreeOffsets",
TGFREEBYTECOUNTS, "FreeByteCounts",
TGGRAYUNIT, "GrayUnit",
TGGRAYCURVE, "GrayCurve",
TGRESOLUTIONUNIT, "ResolutionUnit",
TGPAGENUMBER, "PageNumber",
TGCOLORRESPONSECURVES, "ColorResponseCurves",
TGSOFTWARE, "Software",
TGDATETIME, "DateTime",
TGARTIST, "Artist",
TGHOSTCOMPUTER, "HostComputer",
TGPREDICTOR, "Predictor",
TGWHITEPOINT, "WhitePoint",
TGPRIMARYCHROMATICITIES, "PrimaryChromaticities",
TGCOLORMAP, "ColorMap",
};
/* a particularly greasy static:
*/
DWORD TiffStart = 0L;
/***************************** subroutines ***************************/
/* get tag string
*/
static char defstr[] = "(no string avail)";
void GtTagString (WORD, char **);
LOCAL void GtTagString (tag, ps)
WORD tag;
char **ps;
{
int tablen;
int ii;
tablen = sizeof (tagstr) / sizeof (tagstr[0]);
for (ii = 0; ii < tablen; ii++) {
if (tag == tagstr[ii].tag) {
*ps = tagstr[ii].str;
return;
}
}
*ps = defstr;
}
/* dump an entry
*/
#define MAXVAL 100
RC dumpentry (PDLOC, WORD, DWORD, DIRENTRY *);
LOCAL RC dumpentry (pDloc, ByteOrder, pos, pde)
PDLOC pDloc;
WORD ByteOrder; /* INTELTIFF vs MOTOROLATIFF */
DWORD pos;
DIRENTRY *pde;
{
RC err;
WORD tsize;
WORD BytesToRead;
char *bufptr;
union {
char bytes[MAXVAL];
DWORD dword;
} buf;
WORD maxitems;
WORD item;
char *s;
DWORD valpos;
DWORD ValBuf;
int red;
/* get the non byte reversed value
*/
if (err = VRead (pDloc, pos + 8L, sizeof(ValBuf), (LPSTR)&ValBuf)) {
DBMSG(("dumpentry: VRead error\n"));
return err;
}
/* dump the basic entry
*/
GtTagString (pde->deTag, &s);
DBMSG(("%6lu tag=%5u [%-20.20s] type=%u length=%lu val=0x%.8lx\n",
pos, pde->deTag, s, pde->deType, pde->deLength, ValBuf));
/* print out the value intelligently
*/
if (err = GtTiffSizeof (pde->deType, &tsize)) {
DBMSG(("dumpentry: GtTiffSizeof error\n"));
return err;
}
BytesToRead = tsize * pde->deLength;
maxitems = MAXVAL / tsize;
maxitems = (pde->deLength < (DWORD) maxitems) ?
(WORD)(pde->deLength) : maxitems;
/* careful here: we can't just use deVal to grab data out of, since
* may already have been byte-reversed!
*/
if (BytesToRead <= 4)
valpos = pos + 8L; /* deVal starts on byte 8, wit de */
else
valpos = pde->deVal;
if (err = GtData (pDloc, ByteOrder, valpos, maxitems, pde->deType, buf.bytes)) {
DBMSG(( "dumpentry: GtData error\n"));
return err;
}
bufptr = buf.bytes;
switch (pde->deType) {
case TIFFBYTE:
for (item = 0; item < maxitems; item++)
DBMSG(("%x", (unsigned)(*bufptr++)));
DBMSG(("\n"));
break;
case TIFFASCII:
if (maxitems == 0)
break;
DBMSG(("%.*s\n", maxitems, bufptr));
break;
case TIFFSHORT:
for (item = 0; item < maxitems; item++, bufptr += 2)
DBMSG(("%u ", *((WORD *)bufptr)));
DBMSG(("\n"));
break;
case TIFFLONG:
for (item = 0; item < maxitems; item++, bufptr += 4)
DBMSG(("%lu ", *((DWORD *)bufptr)));
DBMSG(("\n"));
break;
case TIFFRATIONAL:
for (item = 0; item < maxitems; item++) {
DBMSG(("% lu ", *((DWORD *)bufptr)));
bufptr += 4;
DBMSG(("%lu ", *((DWORD *)bufptr)));
bufptr += 4;
}
DBMSG(("\n"));
break;
default:
DBMSG(( "dumpentry: can't get here\n"));
break;
}
return SUCCESS;
}
/***************************** main routine **************************/
#ifdef WINDOWS
int main (int,char **);
int main (ac, av)
#endif
#ifdef MACINTOSH
int _main (int, char **);
int _main (ac, av)
#endif
int ac;
char **av;
{
RC err;
TIFFHDR th;
DIRENTRY de;
WORD entries;
WORD entry;
DWORD location;
DLOC dloc;
DWORD dwtemp;
WORD wtemp;
WORD ByteOrder;
WORD red;
/* check # of args
*/
if (ac != 2) {
DBMSG(("usage: tiffdump filename\n"));
goto cu0;
}
/* open the file
*/
if ((dloc.dlFp = fopen (av[1], "rb")) == (FILE *) NULL) {
DBMSG(("can't open %s\n", av[1]));
goto cu0;
}
DBMSG(("FILE: %s\n", av[1]));
dloc.dlWhere = INFILE;
/* since I use this program to dump TIFF "files" that are embedded in
* other files (a nonstandard thing to do), I will look for a
* plausible start of the TIFF section. TODO: make this more
* general (cycle through TIFF "files") and more robust (check for
* version #, at least).
*/
while ((red = fread ((char *)&ByteOrder, sizeof(WORD), 1, dloc.dlFp)) == 1) {
if (ByteOrder == INTELTIFF || ByteOrder == MOTOROLATIFF)
break;
else
TiffStart += 2L;
}
DBMSG(("TiffStart=%lu\n",TiffStart));
DBMSG(("ByteOrder=%x\n",ByteOrder));
if (red == 0) {
DBMSG(("can't find ByteOrder\n"));
goto quit;
}
#if 0
dloc.dlOrder = ByteOrder;
#endif /* 0 */
/* read the 8-byte header, and dump it
*/
if (err = GtTiffHdr ((PDLOC)&dloc, &th)) {
DBMSG(("can't read header\n"));
goto quit;
}
if (th.thByteOrder == INTELTIFF)
DBMSG(("%6lu ByteOrder = INTELTIFF\n", 0L));
else if (th.thByteOrder == MOTOROLATIFF)
DBMSG(("%6lu ByteOrder = MOTOROLATIFF\n", 0L));
else {
DBMSG(("bad byte order.\n"));
goto quit;
}
DBMSG(("%6lu Version = %d\n", 2L, th.thVersion));
DBMSG(("%6lu IfdOffset = %lu\n", 4L, th.thIfdOffset));
location = th.thIfdOffset;
#if 0
dloc.dlOrder = th.thByteOrder;
#endif /* 0 */
/* loop through the IFD's
*/
do {
/* if ifd location is 0, quit
*/
if (location == 0L) {
DBMSG(("ifd at 0. quit.\n"));
break;
}
/* read the number of entries, and dump it
*/
if (err = GtData ((PDLOC)&dloc, th.thByteOrder, (DWORD)location, 1, TIFFSHORT,
(LPSTR)&entries)) {
DBMSG(("can't read # of entries\n"));
break;
}
DBMSG(("\n%6lu Entries = %d\n", th.thIfdOffset, entries));
if (entries == 0) {
DBMSG(("number of entries is 0. quit.\n"));
break;
}
location += 2;
/* loop through the entries
*/
for (entry = 0; entry < entries; entry++) {
/* read the entry
*/
if (err = GtTiffEntry ((PDLOC)&dloc, th.thByteOrder, location, &de)) {
DBMSG(("can't read entry\n"));
goto quit;
}
/* print the entry in human-readable form
*/
if (err = dumpentry ((PDLOC)&dloc, th.thByteOrder, location, &de)) {
DBMSG(("dumpentry error\n"));
goto quit;
}
/* store the value, for future diagnostic use
*/
/* adjust the current location
*/
location += sizeof (DIRENTRY);
} /* end of entry loop */
/* read the location of the next ifd
*/
if (err = GtData((PDLOC)&dloc, th.thByteOrder, (DWORD)location, 1, TIFFLONG,
(LPSTR)&dwtemp)) {
DBMSG(("%6lu can't read location of the next ifd\n",
location));
goto quit;
}
DBMSG(("%6lu next ifd at %lu\n", location, dwtemp));
location = dwtemp;
} while (1); /* end of ifd loop */
/* now check for errors. We go through a lot of the same work again, since
* this error-checking was an afterthought.
*/
{
IMAG imag;
IMAG *p = &imag;
DBMSG(("\n\n"));
if (err = GtTiffInfo ((PDLOC)&dloc, p)) {
/* DBMSG(("tiffdump: GtTiffInfo\n")); */
goto b0;
}
b1: CloseImag(p);
b0: ;
}
quit: ;
fclose (dloc.dlFp);
cu0: return;
}